#ifndef MEMORY_STRATEGIES_H
#define MEMORY_STRATEGIES_H

#include "unified_memory_interfaces.h"
#include <QDateTime>
#include <QRect>
#include <algorithm>

// TDD: 具体的内存管理策略实现

// 🟢 GREEN: 基于距离的策略（适合主图浏览）
class DistanceBasedStrategy : public IMemoryStrategy {
private:
    int m_keepRange;
    
public:
    explicit DistanceBasedStrategy(int keepRange = 15) : m_keepRange(keepRange) {}
    
    EvictionDecision makeEvictionDecision(
        const QList<ICacheItem*>& items,
        int currentFocus,
        size_t memoryLimit,
        size_t currentUsage,
        double memoryPressure) const override {
        
        EvictionDecision decision;
        
        if (currentUsage <= memoryLimit && memoryPressure < 0.7) {
            decision.reason = "Memory usage within acceptable limits";
            decision.confidence = 1.0;
            return decision;
        }
        
        // 根据内存压力调整保留范围
        int effectiveKeepRange = m_keepRange;
        if (memoryPressure > 0.8) {
            effectiveKeepRange = m_keepRange / 2;  // 高压力时减半
        } else if (memoryPressure > 0.9) {
            effectiveKeepRange = m_keepRange / 4;  // 极高压力时减至1/4
        }
        
        // 清理远离当前焦点的项目
        for (auto* item : items) {
            if (!item->isLoaded()) continue;
            
            int distance = abs(item->getIndex() - currentFocus);
            if (distance > effectiveKeepRange) {
                decision.itemsToEvict.append(item->getIndex());
            }
        }
        
        // 预加载附近项目（根据内存压力调整）
        int preloadRange = qMax(1, effectiveKeepRange / 3);
        for (int i = currentFocus - preloadRange; i <= currentFocus + preloadRange; ++i) {
            if (i >= 0) {
                decision.itemsToPreload.append(i);
            }
        }
        
        decision.reason = QString("Distance-based: keep=%1, preload=%2, pressure=%3")
                         .arg(effectiveKeepRange).arg(preloadRange).arg(memoryPressure, 0, 'f', 2);
        decision.confidence = 1.0 - memoryPressure * 0.3;  // 压力越大置信度越低
        
        return decision;
    }
};

// 🟢 GREEN: 基于可见性的策略（适合缩略图滚动）
class VisibilityBasedStrategy : public IMemoryStrategy {
private:
    int m_bufferSize;
    QRect m_viewport;
    int m_itemHeight;
    
public:
    VisibilityBasedStrategy(int bufferSize = 50, int itemHeight = 200)
        : m_bufferSize(bufferSize), m_itemHeight(itemHeight) {}
    
    void updateViewport(const QRect& viewport) {
        m_viewport = viewport;
    }
    
    EvictionDecision makeEvictionDecision(
        const QList<ICacheItem*>& items,
        int currentFocus,
        size_t memoryLimit,
        size_t currentUsage,
        double memoryPressure) const override {
        
        EvictionDecision decision;
        
        // 计算可见范围
        auto [visibleStart, visibleEnd] = calculateVisibleRange(currentFocus);
        
        // 根据内存压力调整缓冲区
        int effectiveBuffer = m_bufferSize;
        if (memoryPressure > 0.8) {
            effectiveBuffer = m_bufferSize / 2;
        }
        
        int bufferStart = qMax(0, visibleStart - effectiveBuffer);
        int bufferEnd = visibleEnd + effectiveBuffer;
        
        // 清理缓冲区外的项目
        for (auto* item : items) {
            if (!item->isLoaded()) continue;
            
            int index = item->getIndex();
            if (index < bufferStart || index > bufferEnd) {
                // 额外检查：如果内存压力不高且项目最近被访问，暂时保留
                if (memoryPressure < 0.6) {
                    QDateTime now = QDateTime::currentDateTime();
                    if (item->getLastAccessed().secsTo(now) < 30) {
                        continue;  // 最近30秒内访问过，暂时保留
                    }
                }
                
                decision.itemsToEvict.append(index);
            }
        }
        
        // 预加载可见区域内的项目
        for (int i = visibleStart; i <= visibleEnd; ++i) {
            decision.itemsToPreload.append(i);
        }
        
        decision.reason = QString("Visibility-based: visible=[%1,%2], buffer=%3, pressure=%4")
                         .arg(visibleStart).arg(visibleEnd).arg(effectiveBuffer).arg(memoryPressure, 0, 'f', 2);
        decision.confidence = 0.9;  // 可见性策略通常很可靠
        
        return decision;
    }
    
private:
    std::pair<int, int> calculateVisibleRange(int currentFocus) const {
        // 基于当前焦点和视口计算可见范围
        // 简化实现：假设每个项目占用固定高度
        int visibleItems = m_viewport.height() / m_itemHeight;
        int visibleStart = qMax(0, currentFocus - visibleItems / 2);
        int visibleEnd = currentFocus + visibleItems / 2;
        
        return {visibleStart, visibleEnd};
    }
};

// 🟢 GREEN: LRU策略（智能综合策略）
class LRUStrategy : public IMemoryStrategy {
private:
    double m_accessWeightFactor = 2.0;    // 访问频率权重
    double m_distanceWeightFactor = 1.0;  // 距离权重
    double m_timeWeightFactor = 0.5;      // 时间权重
    
public:
    EvictionDecision makeEvictionDecision(
        const QList<ICacheItem*>& items,
        int currentFocus,
        size_t memoryLimit,
        size_t currentUsage,
        double memoryPressure) const override {
        
        EvictionDecision decision;
        
        if (currentUsage <= memoryLimit && memoryPressure < 0.6) {
            decision.reason = "LRU: Memory usage acceptable";
            decision.confidence = 1.0;
            return decision;
        }
        
        // 计算每个项目的优先级分数
        struct ItemScore {
            ICacheItem* item;
            double score;
            size_t memorySize;
        };
        
        QList<ItemScore> scoredItems;
        QDateTime now = QDateTime::currentDateTime();
        
        for (auto* item : items) {
            if (!item->isLoaded()) continue;
            
            ItemScore scored;
            scored.item = item;
            scored.memorySize = item->getMemorySize();
            
            // 计算综合分数（越低越容易被清理）
            double distanceScore = calculateDistanceScore(item->getIndex(), currentFocus);
            double timeScore = calculateTimeScore(item->getLastAccessed(), now);
            double accessScore = 1.0;  // 简化：暂时不考虑访问频率
            
            scored.score = distanceScore * m_distanceWeightFactor +
                          timeScore * m_timeWeightFactor +
                          accessScore * m_accessWeightFactor;
            
            scoredItems.append(scored);
        }
        
        // 按分数排序（分数低的优先清理）
        std::sort(scoredItems.begin(), scoredItems.end(),
                  [](const ItemScore& a, const ItemScore& b) {
                      return a.score < b.score;
                  });
        
        // 清理低分数项目直到内存足够
        size_t targetReduction = currentUsage - memoryLimit;
        size_t freedMemory = 0;
        
        for (const auto& scored : scoredItems) {
            if (freedMemory >= targetReduction) break;
            
            decision.itemsToEvict.append(scored.item->getIndex());
            freedMemory += scored.memorySize;
        }
        
        // 智能预加载：根据访问模式预测
        if (memoryPressure < 0.8) {
            predictivePreload(decision, currentFocus);
        }
        
        decision.reason = QString("LRU: evicted %1 items, freed %2MB, pressure=%3")
                         .arg(decision.itemsToEvict.size())
                         .arg(freedMemory / (1024*1024))
                         .arg(memoryPressure, 0, 'f', 2);
        decision.confidence = 0.8;  // LRU策略相对可靠
        
        return decision;
    }
    
private:
    double calculateDistanceScore(int itemIndex, int currentFocus) const {
        if (currentFocus < 0) return 0.5;  // 无焦点时中等分数
        
        int distance = abs(itemIndex - currentFocus);
        return 1.0 / (1.0 + distance);  // 距离越远分数越低
    }
    
    double calculateTimeScore(const QDateTime& lastAccessed, const QDateTime& now) const {
        qint64 secondsSinceAccess = lastAccessed.secsTo(now);
        return 1.0 / (1.0 + secondsSinceAccess / 60.0);  // 时间越久分数越低
    }
    
    void predictivePreload(EvictionDecision& decision, int currentFocus) const {
        // 简单的预测：基于当前焦点预加载附近项目
        int preloadRange = 3;
        for (int i = currentFocus - preloadRange; i <= currentFocus + preloadRange; ++i) {
            if (i >= 0) {
                decision.itemsToPreload.append(i);
            }
        }
    }
};

// 🟢 GREEN: 系统内存监控器（真实实现）
class SystemMemoryMonitor : public QObject, public IMemoryMonitor {
    Q_OBJECT
private:
    QTimer* m_timer;
    size_t m_totalSystemMemory;
    size_t m_lastAvailableMemory;
    mutable QMutex m_mutex;
    
public:
    explicit SystemMemoryMonitor(QObject* parent = nullptr) : QObject(parent) {
        m_totalSystemMemory = getTotalSystemMemory();
        m_lastAvailableMemory = getAvailableMemory();
        
        m_timer = new QTimer(this);
        connect(m_timer, &QTimer::timeout, this, &SystemMemoryMonitor::updateMemoryInfo);
        m_timer->start(1000);  // 每秒更新
    }
    
    size_t getCurrentMemoryUsage() const override {
        return getCurrentProcessMemoryUsage();
    }
    
    size_t getAvailableMemory() const override {
        QMutexLocker locker(&m_mutex);
        return m_lastAvailableMemory;
    }
    
    double getMemoryPressure() const override {
        QMutexLocker locker(&m_mutex);
        if (m_totalSystemMemory == 0) return 0.0;
        
        return 1.0 - (double(m_lastAvailableMemory) / double(m_totalSystemMemory));
    }
    
    void startMonitoring() override {
        if (m_timer && !m_timer->isActive()) {
            m_timer->start(1000);
        }
    }
    
    void stopMonitoring() override {
        if (m_timer) {
            m_timer->stop();
        }
    }
    
private slots:
    void updateMemoryInfo() {
        QMutexLocker locker(&m_mutex);
        m_lastAvailableMemory = getSystemAvailableMemory();
        
        double pressure = getMemoryPressure();
        if (pressure > 0.9) {
            emit criticalMemoryPressure(pressure);
        } else if (pressure > 0.7) {
            emit highMemoryPressure(pressure);
        }
    }
    
signals:
    void highMemoryPressure(double pressure);
    void criticalMemoryPressure(double pressure);
    
private:
    size_t getTotalSystemMemory() const {
        // 平台特定的实现
#ifdef Q_OS_MACOS
        // macOS实现
        return 16ULL * 1024 * 1024 * 1024;  // 临时：16GB
#elif defined(Q_OS_LINUX)
        // Linux实现
        return 8ULL * 1024 * 1024 * 1024;   // 临时：8GB
#else
        // Windows实现
        return 8ULL * 1024 * 1024 * 1024;   // 临时：8GB
#endif
    }
    
    size_t getSystemAvailableMemory() const {
        // 平台特定的可用内存获取
        // 简化实现，实际需要调用系统API
        return getTotalSystemMemory() / 2;  // 临时：假设50%可用
    }
    
    size_t getCurrentProcessMemoryUsage() const {
        // 获取当前进程内存使用
        // 简化实现，实际需要调用系统API
        return 512 * 1024 * 1024;  // 临时：512MB
    }
};

// 🟢 GREEN: 异常安全的图像工厂
class SafeImageFactory {
public:
    struct CreationResult {
        QImage image;
        bool success = false;
        QString errorMessage;
        size_t actualMemoryUsed = 0;
        QDateTime createdAt;
    };
    
    static CreationResult createImage(int width, int height, 
                                    QImage::Format format = QImage::Format_RGB32) {
        CreationResult result;
        result.createdAt = QDateTime::currentDateTime();
        
        // 预检查参数有效性
        if (width <= 0 || height <= 0) {
            result.errorMessage = QString("Invalid dimensions: %1x%2").arg(width).arg(height);
            return result;
        }
        
        // 计算内存需求
        size_t requiredMemory = calculateMemoryRequirement(width, height, format);
        if (!checkMemoryAvailability(requiredMemory)) {
            result.errorMessage = QString("Insufficient memory: need %1 MB, available %2 MB")
                                 .arg(requiredMemory / (1024*1024))
                                 .arg(getAvailableMemory() / (1024*1024));
            return result;
        }
        
        try {
            // 尝试创建图像
            QImage image(width, height, format);
            
            if (image.isNull()) {
                result.errorMessage = "QImage construction returned null (possible memory allocation failure)";
                return result;
            }
            
            // 验证图像有效性
            if (image.width() != width || image.height() != height) {
                result.errorMessage = QString("Image size mismatch: expected %1x%2, got %3x%4")
                                     .arg(width).arg(height)
                                     .arg(image.width()).arg(image.height());
                return result;
            }
            
            result.image = std::move(image);
            result.success = true;
            result.actualMemoryUsed = result.image.sizeInBytes();
            
        } catch (const std::bad_alloc& e) {
            result.errorMessage = QString("Memory allocation failed: %1").arg(e.what());
        } catch (const std::exception& e) {
            result.errorMessage = QString("Unexpected error during image creation: %1").arg(e.what());
        } catch (...) {
            result.errorMessage = "Unknown exception during image creation";
        }
        
        return result;
    }
    
    // 优雅降级创建
    static CreationResult createImageWithDegradation(int width, int height,
                                                    QImage::Format format = QImage::Format_RGB32) {
        // 首先尝试原始尺寸
        auto result = createImage(width, height, format);
        if (result.success) {
            return result;
        }
        
        // 尝试降级尺寸
        QList<double> scaleFactors = {0.75, 0.5, 0.25, 0.1};
        
        for (double scale : scaleFactors) {
            int scaledWidth = static_cast<int>(width * scale);
            int scaledHeight = static_cast<int>(height * scale);
            
            auto degradedResult = createImage(scaledWidth, scaledHeight, format);
            if (degradedResult.success) {
                degradedResult.errorMessage = QString("Degraded to %1x%2 (scale: %3)")
                                             .arg(scaledWidth).arg(scaledHeight).arg(scale);
                return degradedResult;
            }
        }
        
        // 最后手段：创建最小占位符
        result.errorMessage += " | All degradation attempts failed, returning minimal placeholder";
        result.image = QImage(32, 32, format);
        result.image.fill(Qt::lightGray);
        result.success = result.image.isNull() ? false : true;
        result.actualMemoryUsed = result.image.sizeInBytes();
        
        return result;
    }
    
private:
    static size_t calculateMemoryRequirement(int width, int height, QImage::Format format) {
        int bytesPerPixel = 4;  // 假设32位格式
        switch (format) {
            case QImage::Format_RGB888:
            case QImage::Format_BGR888:
                bytesPerPixel = 3;
                break;
            case QImage::Format_RGB16:
            case QImage::Format_RGB555:
                bytesPerPixel = 2;
                break;
            case QImage::Format_Grayscale8:
            case QImage::Format_Alpha8:
                bytesPerPixel = 1;
                break;
            default:
                bytesPerPixel = 4;  // 安全默认值
        }
        
        return size_t(width) * size_t(height) * bytesPerPixel;
    }
    
    static bool checkMemoryAvailability(size_t required) {
        size_t available = getAvailableMemory();
        return available > required * 2;  // 2倍安全边际
    }
    
    static size_t getAvailableMemory() {
        // 简化实现，实际应该调用系统API
        return 2ULL * 1024 * 1024 * 1024;  // 2GB
    }
};

// 🟢 GREEN: 线程安全的图像容器
class ThreadSafeImageContainer {
private:
    QByteArray m_pixelData;
    int m_width;
    int m_height;
    QImage::Format m_format;
    int m_bytesPerLine;
    
public:
    explicit ThreadSafeImageContainer(const QImage& image) {
        if (image.isNull()) {
            m_width = m_height = 0;
            m_format = QImage::Format_Invalid;
            m_bytesPerLine = 0;
            return;
        }
        
        m_width = image.width();
        m_height = image.height();
        m_format = image.format();
        m_bytesPerLine = image.bytesPerLine();
        
        // 深拷贝像素数据，确保线程安全
        size_t dataSize = m_bytesPerLine * m_height;
        m_pixelData.resize(dataSize);
        memcpy(m_pixelData.data(), image.constBits(), dataSize);
    }
    
    QImage toQImage() const {
        if (m_pixelData.isEmpty()) {
            return QImage();
        }
        
        // 创建新的QImage，拥有独立的内存
        QImage result(reinterpret_cast<const uchar*>(m_pixelData.constData()),
                     m_width, m_height, m_bytesPerLine, m_format);
        
        return result.copy();  // 强制深拷贝，确保内存独立
    }
    
    bool isValid() const {
        return !m_pixelData.isEmpty() && m_width > 0 && m_height > 0;
    }
    
    size_t memoryUsage() const {
        return m_pixelData.size();
    }
    
    QSize size() const {
        return QSize(m_width, m_height);
    }
};

#endif // MEMORY_STRATEGIES_H
